﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using Microsoft.VisualBasic.CompilerServices;

namespace GoldenTuney.Garmin
{
   public class GarminHelper
{
    // Fields
    private decimal _averagePower;
    private decimal _averageSpeed;
    private decimal _if;
    private List<TrackPoint> _rollingAverage;
    private List<int> _rollingAveragePower;
    private decimal _tss;
    private List<TrackPoint> _workoutTrackpoints;

    

    public object caclCTL()
    {
      
        decimal TSB;
        decimal TSSCurrent;

        decimal CTL;
        decimal atl;

        decimal StartingCTL = new decimal();
        decimal StartingATL = new decimal();
        decimal CTLConst = 42M;
        decimal ATLConst = 7M;
        decimal prevCTL = 4M;
        decimal prevATL = 4M;
        List<double> CTLList = new List<double>();
        List<double> ATLList = new List<double>();
        Random r = new Random();
        int index = 1;
        int intMax = 100;
        do
        {
              CTL = new decimal((Convert.ToDouble(this.TSS) * (1.0 - Math.Exp(Convert.ToDouble(decimal.Divide(decimal.MinusOne, CTLConst))))) + (Convert.ToDouble(prevCTL) * Math.Exp(Convert.ToDouble(decimal.Divide(decimal.MinusOne, CTLConst)))));
              atl = new decimal((Convert.ToDouble(this.TSS) * (1.0 - Math.Exp(Convert.ToDouble(decimal.Divide(decimal.MinusOne, ATLConst))))) + (Convert.ToDouble(prevATL) * Math.Exp(Convert.ToDouble(decimal.Divide(decimal.MinusOne, ATLConst)))));
            prevATL = atl;
            prevCTL = CTL;
            CTLList.Add(Convert.ToDouble(CTL));
            ATLList.Add(Convert.ToDouble(atl));
            this.TSS = new decimal(r.Next(0, 130));
            index++;
           intMax = 100;
        }
        while (index <= intMax);
        ATLList.ToArray();
        return ATLList.ToArray();
    }

    public List<TrackPoint> CalcRollingAverage(List<TrackPoint> list, int interval)
    {
        //todo complete the calcRollingAverage
        //DateTime tLast = list[0].Time;
        //DateTime tCurrent = list[0].Time;
        //int n = 0;
        //List<TrackPoint> chunk = new List<TrackPoint>();
        //List<double> finalAveraged = new List<double>();
        List<TrackPoint> finalTrackpoints = new List<TrackPoint>();
        //foreach (TrackPoint tp in list)
        //{
        //    if (tCurrent.Subtract(tLast).Seconds >= 30)
        //    {
        //        tLast = tCurrent;
        //        //todo 
        //        double averageOrderCount =  Aggregate cust In chunk _
        //                Into Average(cust.Power)//Enumerable.Average<TrackPoint>(chunk, new Func<TrackPoint, int>(null, (IntPtr) _Lambda$__18));
        //        chunk = new List<TrackPoint>();
        //        decimal d = new decimal(Math.Pow(averageOrderCount, 4.0));
        //        finalAveraged.Add(Convert.ToDouble(d));
        //        TrackPoint trackpointChunk = new TrackPoint();
        //        trackpointChunk.Power = Convert.ToInt32(d);
        //        trackpointChunk.Time = tCurrent;
        //        finalTrackpoints.Add(trackpointChunk);
        //    }
        //    chunk.Add(tp);
        //    n++;
        //    tCurrent = tp.Time;
        //}
        return finalTrackpoints;
    }

    public static List<TrackPoint> Load(string filename)
    {
        List<TrackPoint> Load = new List<TrackPoint>();

        // List<TrackPoint> Load;
        // List<TrackPoint> l = Enumerable.OrderBy<TrackPoint, double>(Enumerable.Where<TrackPoint>(Enumerable.Select<XElement, TrackPoint>(XDocument.Load(filename).Descendants(XName.Get("Trackpoint", "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2")), new Func<XElement, TrackPoint>(null, (IntPtr) _Lambda$__2)), new Func<TrackPoint, bool>(null, (IntPtr) _Lambda$__3)), new Func<TrackPoint, double>(null, (IntPtr) _Lambda$__4)).ToList<TrackPoint>();
        // List<int[]> dataset = new List<int[]>();
        // List<TrackPoint> tpAveraged = RollingAverage2(l.ToList<TrackPoint>());
        // IEnumerable<int> queryPower = Enumerable.Select<VB$AnonymousType_0<TrackPoint, int>, int>(Enumerable.Select<TrackPoint, VB$AnonymousType_0<TrackPoint, int>>(tpAveraged, new Func<TrackPoint, VB$AnonymousType_0<TrackPoint, int>>(null, (IntPtr) _Lambda$__5)), new Func<VB$AnonymousType_0<TrackPoint, int>, int>(null, (IntPtr) _Lambda$__6));
        // IEnumerable<int> queryAlt = Enumerable.Select<VB$AnonymousType_0<TrackPoint, int>, int>(Enumerable.Select<TrackPoint, VB$AnonymousType_0<TrackPoint, int>>(tpAveraged, new Func<TrackPoint, VB$AnonymousType_0<TrackPoint, int>>(null, (IntPtr) _Lambda$__7)), new Func<VB$AnonymousType_0<TrackPoint, int>, int>(null, (IntPtr) _Lambda$__8));
        // IEnumerable<int> querySpeed = Enumerable.Select<VB$AnonymousType_0<TrackPoint, int>, int>(Enumerable.Select<TrackPoint, VB$AnonymousType_0<TrackPoint, int>>(tpAveraged, new Func<TrackPoint, VB$AnonymousType_0<TrackPoint, int>>(null, (IntPtr) _Lambda$__9)), new Func<VB$AnonymousType_0<TrackPoint, int>, int>(null, (IntPtr) _Lambda$__10));
        // IEnumerable<int> queryHR = Enumerable.Select<VB$AnonymousType_0<TrackPoint, int>, int>(Enumerable.Select<TrackPoint, VB$AnonymousType_0<TrackPoint, int>>(tpAveraged, new Func<TrackPoint, VB$AnonymousType_0<TrackPoint, int>>(null, (IntPtr) _Lambda$__11)), new Func<VB$AnonymousType_0<TrackPoint, int>, int>(null, (IntPtr) _Lambda$__12));
        // return l;
        // dataset.Add(queryPower.ToArray<int>());
        // //TCUser TCUser = new TCUser();
        ///// Workout w = new Workout();
         return Load;
    }

    //public static List<TrackPoint> LoadGPX(string filename)
    //{
    //    //List<TrackPoint> LoadGPX;
    //    //IEnumerable<TrackPoint> query = Enumerable.Select<XElement, TrackPoint>(XDocument.Load(filename).Descendants(XName.Get("trkpt", "http://www.topografix.com/GPX/1/1")), new Func<XElement, TrackPoint>(null, (IntPtr) _Lambda$__1));
    //    //return LoadGPX;
    //}

    public TrainingCenterDatabase_t ReadGarminDatabaseXML(string xml)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(TrainingCenterDatabase_t));
        serializer.UnknownNode += new XmlNodeEventHandler(this.serializer_UnknownNode);
        serializer.UnknownAttribute += new XmlAttributeEventHandler(this.serializer_UnknownAttribute);
        MemoryStream ms = new MemoryStream();
        StreamReader sr = new StreamReader(xml);
        byte[] arrBytData = new UTF8Encoding().GetBytes(xml);
        ms.Write(arrBytData, 0, arrBytData.Length);
        TrainingCenterDatabase_t pe = (TrainingCenterDatabase_t) serializer.Deserialize(sr);
        ms.Close();
        ms = null;
        return pe;
    }

    public static List<TrackPoint> RollingAverage2(List<TrackPoint> list)
    {
        //DateTime tLast = list[0].Time;
        //DateTime tCurrent = list[0].Time;
        //int n = 0;
        List<TrackPoint> chunk = new List<TrackPoint>();
        List<decimal> finalAveraged = new List<decimal>();
        List<TrackPoint> averagedTrackpoins = new List<TrackPoint>();
        //foreach (TrackPoint tp in list)
        //{
        //    if (tCurrent.Subtract(tLast).Seconds >= 30)
        //    {
        //        tLast = tCurrent;
        //        double averageOrderCount = Enumerable.Average<TrackPoint>(chunk, new Func<TrackPoint, int>(null, (IntPtr) _Lambda$__13));
        //        double averageSpeed = Enumerable.Average<TrackPoint>(chunk, new Func<TrackPoint, int>(null, (IntPtr) _Lambda$__14));
        //        double averageHR = Enumerable.Average<TrackPoint>(chunk, new Func<TrackPoint, int>(null, (IntPtr) _Lambda$__15));
        //        double averageCadence = Enumerable.Average<TrackPoint>(chunk, new Func<TrackPoint, int>(null, (IntPtr) _Lambda$__16));
        //        double averageAltitudeMeters = Enumerable.Average<TrackPoint>(chunk, new Func<TrackPoint, double>(null, (IntPtr) _Lambda$__17));
        //        TrackPoint newTP = new TrackPoint();
        //        newTP.Power = (int) Math.Round(averageOrderCount);
        //        newTP.Speed = (int) Math.Round(averageSpeed);
        //        newTP.HeartRate = (int) Math.Round(averageHR);
        //        newTP.Cadence = (int) Math.Round(averageCadence);
        //        newTP.AltitudeMeters = averageAltitudeMeters;
        //        averagedTrackpoins.Add(newTP);
        //        chunk = new List<TrackPoint>();
        //        decimal d = new decimal(Math.Pow(averageOrderCount, 4.0));
        //        finalAveraged.Add(d);
        //    }
        //    chunk.Add(tp);
        //    n++;
        //    tCurrent = tp.Time;
        //}
        return averagedTrackpoins;
    }

    private void serializer_UnknownAttribute(object sender, XmlAttributeEventArgs e)
    {
        XmlAttribute attr = e.Attr;
        Console.WriteLine("Unknown attribute " + attr.Name + "='" + attr.Value + "'");
    }

    private void serializer_UnknownNode(object sender, XmlNodeEventArgs e)
    {
        Console.WriteLine("Unknown Node:" + e.Name + "\t" + e.Text);
    }

    // Properties
    public decimal AveragePower
    {
        get
        {
            return this._averagePower;
        }
        set
        {
            this._averagePower = value;
        }
    }

    public decimal AverageSpeed
    {
        get
        {
            return this._averageSpeed;
        }
        set
        {
            this._averageSpeed = value;
        }
    }

    public decimal IF
    {
        get
        {
            return this._if;
        }
        set
        {
            this._if = value;
        }
    }

    public List<TrackPoint> RollingAverage
    {
        get
        {
            return this._rollingAverage;
        }
        set
        {
            this._rollingAverage = value;
        }
    }

    public List<int> RollingAveragePower
    {
        get
        {
            return this._rollingAveragePower;
        }
        set
        {
            this._rollingAveragePower = value;
        }
    }

    public decimal TSS
    {
        get
        {
            return this._tss;
        }
        set
        {
            this._tss = value;
        }
    }

    public List<TrackPoint> WorkoutTrackpoints
    {
        get
        {
            return this._workoutTrackpoints;
        }
        set
        {
            this._workoutTrackpoints = value;
        }
    }

   

       
}

 
 
 

}
